<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
<meta name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

    <meta name="author" content="kissdata">


    <meta name="subtitle" content="人生笔记">


    <meta name="description" content="南邮计算机学院2021毕业生王鹏的介绍，cs软件工程专业">


    <meta name="keywords" content="wangpeng 王鹏 南邮 南京">


<title>项目经验 | 连接 RabbitMQ | 王鹏的小岛</title>



    <link rel="icon" href="/myIcon.ico">




    <!-- stylesheets list from _config.yml -->
    
    <link rel="stylesheet" href="/css/style.css">
    



    <!-- scripts list from _config.yml -->
    
    <script src="/js/script.js"></script>
    
    <script src="/js/tocbot.min.js"></script>
    



    
    
        <!-- MathJax配置，可通过单美元符号书写行内公式等 -->
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
    "HTML-CSS": {
        preferredFont: "TeX",
        availableFonts: ["STIX","TeX"],
        linebreaks: { automatic:true },
        EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50)
    },
    tex2jax: {
        inlineMath: [ ["$", "$"], ["\\(","\\)"] ],
        processEscapes: true,
        ignoreClass: "tex2jax_ignore|dno",
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
    },
    TeX: {
        equationNumbers: { autoNumber: "AMS" },
        noUndefined: { attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "90%" } },
        Macros: { href: "{}" }
    },
    messageStyle: "none"
    });
</script>
<!-- 给MathJax元素添加has-jax class -->
<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>
<!-- 通过连接CDN加载MathJax的js代码 -->
<script type="text/javascript" async
        src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
</script>


    


<meta name="generator" content="Hexo 7.0.0"></head>

<body>
    <script>
        // this function is used to check current theme before page loaded.
        (() => {
            const currentTheme = window.localStorage && window.localStorage.getItem('theme') || '';
            const isDark = currentTheme === 'dark';
            const pagebody = document.getElementsByTagName('body')[0]
            if (isDark) {
                pagebody.classList.add('dark-theme');
                // mobile
                document.getElementById("mobile-toggle-theme").innerText = "· Dark"
            } else {
                pagebody.classList.remove('dark-theme');
                // mobile
                document.getElementById("mobile-toggle-theme").innerText = "· Light"
            }
        })();
    </script>

    <div class="wrapper">
        <header>
    <nav class="navbar">
        <div class="container">
            <div class="navbar-header header-logo"><a href="/">侠之大者</a></div>
            <div class="menu navbar-right">
                
                    <a class="menu-item" href="/update/mystate">Career</a>
                
                    <a class="menu-item" href="/category">Legend</a>
                
                    <a class="menu-item" href="/about">Me</a>
                
                <input id="switch_default" type="checkbox" class="switch_default">
                <label for="switch_default" class="toggleBtn"></label>
            </div>
        </div>
    </nav>

    
    <nav class="navbar-mobile" id="nav-mobile">
        <div class="container">
            <div class="navbar-header">
                <div>
                    <a href="/">侠之大者</a><a id="mobile-toggle-theme">·&nbsp;Light</a>
                </div>
                <div class="menu-toggle" onclick="mobileBtn()">&#9776; Menu</div>
            </div>
            <div class="menu" id="mobile-menu">
                
                    <a class="menu-item" href="/update/mystate">Career</a>
                
                    <a class="menu-item" href="/category">Legend</a>
                
                    <a class="menu-item" href="/about">Me</a>
                
            </div>
        </div>
    </nav>

</header>
<script>
    var mobileBtn = function f() {
        var toggleMenu = document.getElementsByClassName("menu-toggle")[0];
        var mobileMenu = document.getElementById("mobile-menu");
        if(toggleMenu.classList.contains("active")){
           toggleMenu.classList.remove("active")
            mobileMenu.classList.remove("active")
        }else{
            toggleMenu.classList.add("active")
            mobileMenu.classList.add("active")
        }
    }
</script>
            <div class="main">
                <div class="container">
    
    
        <div class="post-toc">
    <div class="tocbot-list">
    </div>
    <div class="tocbot-list-menu">
        <a class="tocbot-toc-expand" onclick="expand_toc()">Expand all</a>
        <a onclick="go_top()">Back to top</a>
        <a onclick="go_bottom()">Go to bottom</a>
    </div>
</div>

<script>
    var tocbot_timer;
    var DEPTH_MAX = 6; // 为 6 时展开所有
    var tocbot_default_config = {
        tocSelector: '.tocbot-list',
        contentSelector: '.post-content',
        headingSelector: 'h1, h2, h3, h4, h5',
        orderedList: false,
        scrollSmooth: true,
        onClick: extend_click,
    };

    function extend_click() {
        clearTimeout(tocbot_timer);
        tocbot_timer = setTimeout(function() {
            tocbot.refresh(obj_merge(tocbot_default_config, {
                hasInnerContainers: true
            }));
        }, 420); // 这个值是由 tocbot 源码里定义的 scrollSmoothDuration 得来的
    }

    document.ready(function() {
        tocbot.init(obj_merge(tocbot_default_config, {
            collapseDepth: 1
        }));
    });

    function expand_toc() {
        var b = document.querySelector('.tocbot-toc-expand');
        var expanded = b.getAttribute('data-expanded');
        expanded ? b.removeAttribute('data-expanded') : b.setAttribute('data-expanded', true);
        tocbot.refresh(obj_merge(tocbot_default_config, {
            collapseDepth: expanded ? 1 : DEPTH_MAX
        }));
        b.innerText = expanded ? 'Expand all' : 'Collapse all';
    }

    function go_top() {
        window.scrollTo(0, 0);
    }

    function go_bottom() {
        window.scrollTo(0, document.body.scrollHeight);
    }

    function obj_merge(target, source) {
        for (var item in source) {
            if (source.hasOwnProperty(item)) {
                target[item] = source[item];
            }
        }
        return target;
    }
</script>
    

    
    <article class="post-wrap">
        <header class="post-header">
            <h1 class="post-title">项目经验 | 连接 RabbitMQ</h1>
            
                <div class="post-meta">
                    
                        Author: <a itemprop="author" rel="author" href="/">kissdata</a>
                    

                    
                        <span class="post-time">
                        Date: <a href="#">Oct 24, 2022&nbsp;&nbsp;0:00</a>
                        </span>
                    
                    
                        <span class="post-category">
                    Category:
                            
                                <a href="/categories/Review/">Review</a>
                            
                        </span>
                    
                </div>
            
        </header>

        <div class="post-content">
            <p>【Highlights】本文属于 <code>消息队列</code> 方面的知识，按 记录缘由（哪个项目遇到） - 基础概述 - 什么困难 - 怎么解决的 顺序写。</p>
<table>
<thead>
<tr>
<th>Tools</th>
<th>Size</th>
<th>Version</th>
</tr>
</thead>
<tbody><tr>
<td>RabbitMQ</td>
<td>14.6 M</td>
<td><a target="_blank" rel="noopener" href="https://github.com/rabbitmq/rabbitmq-server/releases/">v 3.12</a></td>
</tr>
<tr>
<td>Erlang</td>
<td>113 M</td>
<td><a target="_blank" rel="noopener" href="https://github.com/erlang/otp/releases">v 25.1</a></td>
</tr>
</tbody></table>
<h1 id="一、技术简介"><a href="#一、技术简介" class="headerlink" title="一、技术简介"></a>一、技术简介</h1><p>rabbitmq是我见过的第一个中间件，对它阴影较大，因为他，直接导致了一个员工才来了半个月就辞职了。</p>
<p>当时想将图片的信息数据传送到其他模块中。选取的RabbitMQ作为中间件。</p>
<p>【rabbitMQ 作用】1 把一个同步请求转成异步，提高用户体验度；2 实现项目之间的解耦合；3 流量削峰（适用于秒杀功能）</p>
<blockquote>
<p>给自己提个醒，这里新知识学习的时候，不用亦步亦趋地跟着网课教程讲的那样背书，比如作用罗列，肯定不止这些，记得3个就好了。比如 削峰，第一次碰见这个词还兴奋得不得了，好像知道了什么新知识，其实没有，不能陷入假知识的陷阱。</p>
</blockquote>
<p>【常见中间件比较】</p>
<ul>
<li>rocket MQ —— 阿里开源；适用于订单交易（能保证消息的顺序）；收费</li>
<li>rabbit MQ —— Erlang语言；适用于企业ESB整合；支持负载均衡和数据持久化</li>
<li>Active MQ —— 只适用在消息在短时间内被消费的场景（不适应消息量巨大的情况）</li>
<li>kafka</li>
</ul>
<h3 id="学习参考"><a href="#学习参考" class="headerlink" title="学习参考"></a>学习参考</h3><p> <a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV183411c7ES">https://www.bilibili.com/video/BV183411c7ES</a></p>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_43279457/article/details/118055590">Golang操作Rabbitmq</a> (CSDN 2021-06)</p>
<p><a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/373383382">RabbitMQ安装介绍并用Go实践</a> (知乎 2021-05)</p>
<p>AMQP概念 <a target="_blank" rel="noopener" href="http://rabbitmq.mr-ping.com/AMQP/AMQP_0-9-1_Model_Explained.html">AMQP 0.9.1 模型解析 · RabbitMQ</a></p>
<ul>
<li>AMQP 主要包含交换机和队列</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">graph LR;</span><br><span class="line">	id1(发布者)--信道--&gt; id2(交换机)--&gt; id3(队列)--&gt;id4(消费者);</span><br></pre></td></tr></table></figure>

<p><img src="https://upload-images.jianshu.io/upload_images/5630287-4e4ee7999ff36459.png" alt="5630287-4e4ee7999ff36459.png"></p>
<p>交换机相当于路由器，队列相当于网线，一个交换机可以有多个队列，发的时候直接发到交换机。</p>
<h1 id="二、安装和使用"><a href="#二、安装和使用" class="headerlink" title="二、安装和使用"></a>二、安装和使用</h1><h3 id="window"><a href="#window" class="headerlink" title="window"></a>window</h3><p>知乎有安装方法，主要3步，（1）先安装Erlang，设置环境变量 <code>ERLANG_HOME</code>  和 Path；（2）下载 rabbitmq-server <a target="_blank" rel="noopener" href="https://www.rabbitmq.com/install-windows.html">page</a>， 直接安装；设置环境变量 <code>RABBITMQ_HOME</code> 和 Path（3）启动控制台插件，cmd命令输入</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">:<span class="comment"># 进入sbin目录</span></span><br><span class="line">cd C:\Program Files\RabbitMQ Server\rabbitmq_server-<span class="number">3.11</span>.<span class="number">2</span>\sbin</span><br><span class="line">:<span class="comment"># 安装插件</span></span><br><span class="line">rabbitmq-plugins enable rabbitmq_management</span><br><span class="line"></span><br><span class="line">:<span class="comment"># 附其他操作</span></span><br><span class="line">rabbitmqctl stop   // 关闭</span><br><span class="line">rabbitmq-service start // 开启服务</span><br></pre></td></tr></table></figure>

<p>【坑1】rabbitmq的安装路径不能有空格，否则15672端口的网页打不开。</p>
<h1 id="三、Go连接"><a href="#三、Go连接" class="headerlink" title="三、Go连接"></a>三、Go连接</h1><p>循环连接rabbitMQ直到连接成功</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">connRabbitMQ</span><span class="params">(rmqConnInfo RmqConnInfo)</span></span> *amqp.Connection &#123;</span><br><span class="line">	connUrl := rmqConnInfo.RmqUserName + <span class="string">&quot;:&quot;</span> + rmqConnInfo.RmqPassword + <span class="string">&quot;@&quot;</span> +</span><br><span class="line">		rmqConnInfo.RmqHost + <span class="string">&quot;:&quot;</span> + rmqConnInfo.RmqPort + <span class="string">&quot;/&quot;</span></span><br><span class="line">	<span class="keyword">var</span> rbConn *amqp.Connection</span><br><span class="line"></span><br><span class="line">	<span class="keyword">var</span> err <span class="type">error</span></span><br><span class="line">	<span class="keyword">for</span> &#123;</span><br><span class="line">		rbConn, err = amqp.Dial(<span class="string">&quot;amqp://&quot;</span> + connUrl)</span><br><span class="line">		<span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">			xdev.Log.Error(<span class="string">&quot;无法连接 RabbitMQ: &quot;</span>, connUrl)</span><br><span class="line">			time.Sleep(<span class="number">3</span> * time.Second)</span><br><span class="line">		&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">			<span class="keyword">break</span></span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	xdev.Log.Info(<span class="string">&quot;连接 RabbitMQ成功: &quot;</span>, connUrl)</span><br><span class="line">	<span class="keyword">return</span> rbConn</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">//......	</span><br><span class="line">rbConn := connRabbitMQ(RmqConnInfo&#123;&quot;172.16.0.26&quot;, &quot;5672&quot;, &quot;wangpeng&quot;, &quot;123456&quot;&#125;)</span><br><span class="line">	defer rbConn.Close()</span><br><span class="line"></span><br><span class="line">	rbChannel, err := rbConn.Channel()</span><br><span class="line">	if err != nil &#123;</span><br><span class="line">		xdev.Log.Error(&quot;无法打开信道&quot;, err.Error())</span><br><span class="line">	&#125;</span><br><span class="line">	defer rbChannel.Close()</span><br><span class="line"></span><br><span class="line">	if err := rbChannel.ExchangeDeclare(vFrame.Topic, &quot;fanout&quot;, false, false, false, false, nil); err != nil &#123;</span><br><span class="line">		xdev.Log.Error(err)</span><br><span class="line">	&#125;</span><br><span class="line">	xdev.Log.Info(&quot;rabbitMQ即将使用, 已经创建交换机，交换机名：&quot;, vFrame.Topic)</span><br><span class="line">//......</span><br></pre></td></tr></table></figure>

<h3 id="发布"><a href="#发布" class="headerlink" title="发布"></a>发布</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">if err = rbChannel.Publish(vFrame.Topic,</span><br><span class="line">	&quot;&quot;,</span><br><span class="line">	false,</span><br><span class="line">	false,</span><br><span class="line">	amqp.Publishing&#123;ContentType: &quot;text/plain&quot;, Body: bufferOutput.Bytes()&#125;,</span><br><span class="line">); err != nil &#123;</span><br><span class="line">	xdev.Log.Error(err)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


        </div>

        
            <section class="post-copyright">
                
                
                
                
                     <p class="copyright-item">
                         <span>Slogan:</span>
                         <span>人生三大错觉：我躲得过去，我能反杀，是不是<strong>喜欢我?</strong></span>
                     </p>
                

            </section>
        
        <section class="post-tags">
            <div>
            </div>
            <div>
                <a href="javascript:window.history.back();">back</a>
                <span>· </span>
                <a href="/">home</a>
            </div>
        </section>
        <section class="post-nav">
            
                <a class="prev" rel="prev" href="/2022/11-16/deploy_sdl2/">🆗 | Windows 配置SDL2库</a>
            
            
            <a class="next" rel="next" href="/2022/10-3/centos_sql/">开发环境 | CentOS 安装各种数据库</a>
            
        </section>


    </article>
</div>

            </div>
            <footer id="footer" class="footer">
    <div class="copyright">
        <span>187-9597-5517 &nbsp; 王鹏 @ <a href="https://cs.njupt.edu.cn/" target="_blank">njupt</a</span>
    </div>
</footer>

    </div>
</body>

</html>